package _caolihua;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.ansj.domain.Term;
import org.ansj.recognition.NatureRecognition;
import org.ansj.splitWord.analysis.ToAnalysis;
import org.ansj.util.FilterModifWord;
import org.apache.log4j.Logger;
import org.nlpcn.commons.lang.tire.domain.Forest;
import org.nlpcn.commons.lang.tire.library.Library;

import com.kd.crawler.common.utils.StringUtils;
import com.kd.utils.DateUtils;


/**
 * 
 * @author caolh
 *
 */
public class SyncAnalyzer {

	private static final Logger logger = Logger.getLogger(SyncAnalyzer.class);

	public static NewsDocument analyse(String html, String url){
		NewsDocument doc =new NewsDocument();
		String htmltxt = html;
		//简易正则和排除注释干扰
		htmltxt = htmltxt.replaceAll("[\\s&&[^ ]]", "");
		htmltxt = htmltxt.toLowerCase();
		//预处理子串
		String subHtmltxt="";
		System.out.println(htmltxt);
		Term term =null;
		String name="";
		String nature="";
		String title="";//标题
		String date="";//时间
		Long dateLong=0l;
		String content="";//正文
		String subSentence="";//临时<p>句子</p>-->这样的整体，为了可以通过语义分析排除干扰因素
		List<String> sentences= new ArrayList<String>();//未处理的子局集合，最后去标签合并形成content
		String author="";//单个作者类型
		List<String> allAuthors = new ArrayList<String>();//分词结果出现的所有作者
		Set<String> authorKinds = new HashSet<String>();//去重之后的所有作者
		Map<String,Integer> authorAndNumMap = new HashMap<String,Integer>();//作者及出现的次数
		String div="";//单个div类型
		Set<String>divKinds = new HashSet<String>();//去重之后的所有div标记
		Map<String,String>divAndSubSentenceMap = new HashMap<String,String>();
		
		
		boolean flag_p=false;	//正文标识位，true表示<p>标签为打开状态；false为闭合状态
		boolean flag_pcan =true; //默认为true，表示<p>里面的都可以拼接除非遇到pout类型，表示这部分的<p>里面是不可拼接的
		boolean flag_li=false;	//若嵌套了<p>标签，则为脏数据，不要
		boolean flag_font=false;
		int divIndex=0; //发现p,向前定位div
	
		List<Term> terms =null;
		
		//正文处理
		{
			//正文分词预处理，去掉干扰标签
			//如果有<h1>标签，则截取这之后的，这之前可能存在<p>标签的干扰;论坛就是
			//论坛的文章有以<font>嵌入内容的
			Matcher mH1 =null;
			 if(( mH1 =  Pattern.compile("<h1[^>]*?>(.*?)</h1>").matcher(htmltxt)).find()){
				 //subHtmltxt=htmltxt.substring(htmltxt.indexOf("<h1"));
				 subHtmltxt=htmltxt;
				}else{
					subHtmltxt=htmltxt;
				}
			//去掉注释
			 subHtmltxt=subHtmltxt.replaceAll("<!--.*?-->", "");
			 //去掉<meta> 不能去，提供作者有效概率
			 //subHtmltxt=subHtmltxt.replaceAll("<meta.*?>", "");
			 //去掉<script>
			subHtmltxt=subHtmltxt.replaceAll("<script.*?</script>", "");
			//预先去掉<p>或<font>标签里面的一些绝对不可能脏数据，依赖标签，必须预先处理
			 {
				 //正文右上角   参与评论(0)  打印,都是<font>标签内嵌
				 //subHtmltxt=subHtmltxt.replaceAll("<font.*?>\\s*打印\\s*</font>", "").replaceAll("<font.*?>\\s*\\d\\s*</font>", "");
			 }
			//暂时不截取h1，截取会损失掉作者有效性概率
			 //利用pcan筛选文章前、文章后的脏数据
			 
		   terms=ToAnalysis.parse(subHtmltxt, dict_clh);
			new NatureRecognition(terms).recognition();
			terms = FilterModifWord.modifResult(terms);
			System.out.println("截取的subHtmltxt:"+subHtmltxt);
			int termsLength=terms.size();
			//System.out.println("分词总数："+termsLength);
			 for(int i=0;i<termsLength;i++){
					term = terms.get(i);
					name = term.getName();
					nature = term.getNatureStr();
					System.out.println(name+"\t"+nature);
						//排除页面末尾非文章不部分多个<li>里面嵌套<p>
						//字母符号分词不存在最长优先匹配，中文才会有
					
						//预先分词判定,若不为空，后面的就不执行了，在于以后可以机器学习网站名，不必采用正则匹配了
						if(nature.equals("author")){
							//去除掉正文里提到的作者
							//有干扰，比如举办什么大赛，里面提到了很多某个网站。
							if(flag_p){
								
							}else{
								allAuthors.add(name);
							}
						
						}
					
						//排除掉li里面嵌套的p标签-------------------------------------------------------
						if(name.equals("<li>")){
							flag_li=true;
						}
						if(name.equals("</li>")){
							flag_li=false;
						}
						 
						if(flag_li){
							continue;
						}else{
							//启动拼接
							//<p>嵌入了文章-------------------------------------------------------------------
							if(name.equals("<p>")||name.equals("<p")){
								//向前搜索，找到最临近的div
								for(  divIndex=i-1;divIndex>0;divIndex--){
									if(terms.get(divIndex).getName().equals("<div")||terms.get(divIndex).getName().equals("<div>")){
										break;
									}
								}
								flag_p=true;
							}
							
							if(name.equals("</p>")){
								
									if(flag_pcan){
										//此单元标签句子已是一个完整句子
										subSentence = subSentence+name;
										//每个子句都带有一个附属div标记
										sentences.add("<div"+divIndex+">"+subSentence);
										divKinds.add("<div"+divIndex+">");
										subSentence="";
										flag_p=false;
										flag_pcan=true;
									}else{
										subSentence="";
										flag_p=false;
										flag_pcan=true;
									}
							
							}
							//语义分析，拼接状态开启时，判断标签里是否含有不可拼接词句
							if(flag_p){
								//以后直接动态配置词典库即可
								//有的<p>里面嵌套<img
								if(nature.equals("pcan")){
									flag_pcan=false;
								}
								subSentence = subSentence+name;
								
							}
							
							
							//<font>嵌入文章-------------------------------------------------------------------
							if(name.equals("<font>")||name.equals("<font")){
								flag_font=true;
							}
							
							if(name.equals("</font>")){
								if(flag_pcan){
									//此单元标签句子已是一个完整句子
									subSentence = subSentence+name;
									sentences.add(subSentence);
									subSentence="";
									flag_font=false;
									flag_pcan=true;
								}else{
									subSentence="";
									flag_font=false;
									flag_pcan=true;
								}
							}
							
							if(flag_font){
								
								if(nature.equals("pcan")){
									flag_pcan=false;
								}
								subSentence = subSentence+name;
							}
							
							
							// <br />获取文章片段:前向搜索------------------------------------------------------------------
							
							if(name.equals("<br />")){
								
								for(int brIndex=i-1;brIndex>0;brIndex--){
									subSentence = terms.get(brIndex).getName() + subSentence;
								
									if( terms.get(brIndex).getName().equals(">")||terms.get(brIndex).getName().equals("<br />")){
										sentences.add(subSentence);
										subSentence="";
										break;
										
									}
								}
							}
							
							
							
							
							//根据语义，遇到必定是文章结束的词
							//可以排除后续的干扰，如其他网站作者
							if(nature.equals("end")){
								break;
							}
							
							
							
						}
						
						
				
				}
		}
		
	
		System.out.println("--------------------------------------------------分词结束---------------------------------------------------------");
		//拼接句子及打标记处理---------------------------------------------------------------------------------------------------------------------------
		{
			
			
			int sentencesLength=sentences.size();
			for(String s:divKinds){
				
				String tempDivSentence="";
				for(int i=0;i<sentencesLength;i++){
					//System.out.println("--------------------------------------------测试打印每个<p>....</p>子句------------------------------------------");
					//System.out.println(sentences.get(i));
					if(sentences.get(i).contains(s)){
						tempDivSentence=tempDivSentence+sentences.get(i);
					}
				}
				tempDivSentence=tempDivSentence.replaceAll("<div.*?>", "");
				System.out.println("一个div里的结果:      "+tempDivSentence);
				divAndSubSentenceMap.put(s, tempDivSentence);
					
			}
			
			//优选出所有div布局中是正文的部分
			Iterator iter = divAndSubSentenceMap.entrySet().iterator();
			String key="";//div种类
			String val="";//该div种类下包含的所有句子
			int max_chn_nums=0;
			int count=0;
			while(iter.hasNext()){
				Map.Entry<String, String>entry = (Map.Entry<String, String>)iter.next();
				key = entry.getKey();
				val= entry.getValue();
				char[] valCharTemp = val.toCharArray();
				int valCharTempLength=valCharTemp.length;
				for(int i=0;i<valCharTempLength;i++){
					 if (Character.toString(valCharTemp[i]).matches("[\\u4E00-\\u9FA5]+")) {
				            count ++;
				        }
				}
				if(count>=max_chn_nums){
					max_chn_nums=count;
					content=val;
					count=0;
				}
				
			}
			
		}
		
		System.out.println("优选结果:      "+content);
		
		
		//2.日期处理--------------------------------------------------------------------------------------------------------------------------------------
		{
			Map<Long,Matcher> map = new HashMap<Long,Matcher>();
			 map=DateUtils.matchDate2(htmltxt);
			Iterator iter = map.entrySet().iterator(); 
			Long key=null;
			Matcher val =null;
			if (iter.hasNext()) { 
				Map.Entry<Long,Matcher> entry = (Map.Entry<Long,Matcher>) iter.next(); 
				 key = entry.getKey(); 
				 val = entry.getValue(); //得到匹配的matcher
			}
			SimpleDateFormat sdf= new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
			java.util.Date dt = new Date(key);  
			date = sdf.format(dt);  
			dateLong= key;
		}
		
		//3.标题处理--------------------------------------------------------------------------------------------------------------------------------------
		{
			//这里分割不好分
			
			//   <h1>欧联-鲁尼传射伊布造乌龙 马塔进球曼联4-0排第2</h1>
			Matcher m =null;
		
			//有的<h1>里面放的不一定是标题,以h1优先级最高
			 if(( m = Pattern.compile("<h1[^>]*?>(.*?)</h1>").matcher(subHtmltxt)).find()){
				 title = m.group(1);
				//中间以-或中文-分割标题和作者
			}else if(( m =  Pattern.compile("<title[^>]*?>(.*?)[_-]"+author+"(.*?)</title>").matcher(subHtmltxt)).find()){
				 title = m.group(1);
				//  <title>(欧联-鲁尼传射伊布造乌龙 马塔进球曼联4-0排第2)_体育_环球网</title>
			} else if(( m =  Pattern.compile("<title[^>]*?>(.*?)[_-](.*?)[_](.*?)</title>").matcher(subHtmltxt)).find()){
				title = m.group(1)+m.group(2);
				//先从最复杂的开始拼配，最后是才满足最简单的
				//LOL世界总决赛-腾讯网
			}else if(( m =  Pattern.compile("<title[^>]*?>(.*?)[_-](.*?)</title>").matcher(subHtmltxt)).find()){
				 title = m.group(1);
			}else if(( m =  Pattern.compile("<title[^>]*?>(.*?)</title>").matcher(subHtmltxt)).find()){
				title=m.group(1);
			}
			 //去掉里面的标签
			 //<h1 class="ts"><a href="thread-8547699-1-1.html" id="thread_subject">高州市成功申报美丽乡村标准化试点项目！</a> </h1>
			title=title.replaceAll("\\s{2}", "");
			title=title.replaceAll("<.*?>", "");
		}
		
		//4.作者
		{		
				//论坛作者采用论坛名
				/*最优先的根据  来源：后面的，如果没有，一个网页该网站必然在各种标签里面有该网站的一些描述语，我们把这些标签内容去掉后得到subHtmltxt，根据词典库
				优选出频率最高的，此时这个作者最具有说服力,如果词典库还没有，再根据title标签里的作者
				*/
				//有的网站，没有写来源，但是是按照下面的格式，只能采用优选法
				Matcher m =null;
				//2个span
				//<span>来源：<em id="source">新华社</em></span>
				if((m=Pattern.compile("<span.*?来源[:：](.*?)</span>").matcher(subHtmltxt)).find()){
					author =m.group(1);
				}
				//2个span
				//来源、作者嵌入到一个p标签里
				//  <p class="p_time"><span class="ss02">来源：</span><span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><span itemprop="name" class="ss03">侠客岛</span></span></p>
				else if((m=Pattern.compile("<p.*?<span.*?>来源[:：]</span>(.*?)</p>").matcher(subHtmltxt)).find()){
					author =m.group(1);
				}
				//3个span
				//  <span class="sc" id="source_baidu" >来源：<span id="media_span" itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><span itemprop="name">新华网</span></span></span>
				else if((m=Pattern.compile("<span.*?>来源[:：](.*)</span></span></span>").matcher(subHtmltxt)).find()){
					author =m.group(1);
				}
				//1个div
				//<div class="ep-time-soure cDGray">2016-11-27 11:24:34　来源: <a id="ne_article_source" href=http://mp.weixin.qq.com/s/2jSSkE7p1zYGX8VQQr9pDg target=_blank rel="nofollow">央视新闻</a>    </div>
				//<div class="laiyuan">来源：大洋网　　　时间： 2016-11-29 08:41</div>
				else if((m=Pattern.compile("<div.*?来源[：:](.*?)</div>").matcher(subHtmltxt)).find()){
					author =m.group(1);
					
				}
				//考虑到了已经加入词典库的作者
				//来源后面的找不到，根据这个最多词典库概率的
				else if(allAuthors.size()>=0){
					
					//极端情况:文章p标签里出现了大量的其他网站的名字，比如举办什么大赛，由什么网站举行，大量提到，会起到干扰作用
					
					for(int i=0;i<allAuthors.size();i++){
						authorKinds.add(allAuthors.get(i));
					}
					//去重后遍历统计各种作者出现次数
					for(String s:authorKinds){
						int k=0;
						for(int i=0;i<allAuthors.size();i++){
							
							if(allAuthors.get(i).equals(s)){
								k++;
							}
						
						}
						authorAndNumMap.put(s, k);
					}
					
					Iterator iterator = authorAndNumMap.entrySet().iterator();
					String key="";
					Integer num=0;
					Integer maxNum=0;
					//依据词典库里的作者，找到概率最大的
					while(iterator.hasNext()){
						Map.Entry<String, Integer>entry = (Map.Entry<String, Integer>)iterator.next();
						key=entry.getKey();
						num=entry.getValue();
						//两个相等情况，暂不考虑
						if(num>=maxNum){
							maxNum=num;
							author=key;
						}
						//System.out.println(key+num);
					}
					
				}else if(( m =  Pattern.compile("<title[^>]*?>(.*?)[_-](.*?)</title>").matcher(subHtmltxt)).find()){
					author = m.group(2);
				}
				//去掉所有带标签的
				author=author.replaceAll("<.*?>", "").replaceAll("\\s", "").replaceAll("[:：]", "").replaceAll("&nbsp;", " ");
				//来源：新华社　　　时间： 2016-11-28 07:48  放到一个div标签里了
				if(author.contains("时间")){
					author=author.substring(0,author.indexOf("时间"));
				}
			
		}
		
		//去掉脏标签及里面的内容
		//拼接完毕，<p>内嵌标签及内嵌标签里面内容去除
		//有些标签是由于写网页的开发人员<p>，没有用</p>，这样就把一些脏标签包含进来了
		{
			Matcher m =null;
			
			if(content.contains("<a href=")){
				if((m=Pattern.compile("<a href=.*?</a>").matcher(content)).find()){
					content=content.replaceAll("<a href=.*?</a>", "");
				}
			}
			if(content.contains("<span")){
				if((m=Pattern.compile("<span.*?>").matcher(content)).find()){
					content=content.replaceAll("<span.*?>", "");
					content=content.replaceAll("</span>", "");
				}
			}
			//去掉<p>里面的<a
			if(content.contains("<a")){
				if((m=Pattern.compile("<a.*?</a>").matcher(content)).find()){
					content=content.replaceAll("<a.*?</a>", "");
				}
			}
			if(content.contains("<script")){
				if((m=Pattern.compile("<script.*?</script>").matcher(content)).find()){
					content=content.replaceAll("<script.*?</script>", "");
				}
			}
			//<p>里面可以嵌套<table>
			if(content.contains("<table")){
				if((m=Pattern.compile("<table.*?</table>").matcher(content)).find()){
					content=content.replaceAll("<table.*?</table>", "");
				}
			}
			if(content.contains("<em")){
				if((m=Pattern.compile("<em.*?</em>").matcher(content)).find()){
					content=content.replaceAll("<em.*?</em>", "");
				}
			}
			
			
			//去掉脏标签
			//拼接的<p>标签里面有的字体加粗了,去掉这<strong>符号
			content=content.replaceAll("<strong.*?>", "").replaceAll("</strong>", "");
			content=content.replaceAll("&nbsp;", " ");
			content=content.replaceAll("&gt;", "");
			content=content.replaceAll("\\s{2}", "");
			content=content.replaceAll("<p.*?>", "").replaceAll("</p>", "");
			content=content.replaceAll("<img.*?/>", "");
			content=content.replaceAll("<br.*?/>", "");//换行符
			content=content.replaceAll("<font.*?>", "").replace("</font>", "");//以<font>为标签的段落 
			//替换为中文双引号
			content=content.replaceAll("&ldquo;", "“").replaceAll("&rdquo;", "”");
			//替换为-
			content=content.replaceAll("&mdash;", "-");
			content=content.replaceAll("<div.*?>", "").replaceAll("</div>", "");
			content=content.replaceAll("<iframe.*?>", "").replaceAll("</iframe>", "");
			
			
			//文章末尾有的<p>标签里面嵌入了<button...>，这一部分到最后全部删除掉,这是最后处理的!
			if(content.contains("<button")){
				content=content.substring(0,content.indexOf("<button"));
			}
			
		}
		

		System.out.println("-----------------------------------------匹配结果Begin--------------------------------------------------");
		System.out.print("标题:");
		System.out.println("《"+title+"》");
		System.out.print("时间：");
		//System.out.println(dateLong);
		System.out.println(date);
		System.out.print("作者：");
		System.out.println(author);
		System.out.print("正文：");
		System.out.println(content);
		System.out.println("-----------------------------------------匹配结果End--------------------------------------------------");
		doc.setAuthor(author);
		doc.setTitle(title);
		doc.setContent(content);
		doc.setDate(dateLong);
		doc.setUrl(url);
		doc.setCommentNums(0);
		//logFor(title,dateLong,author,content,url);
		return doc;
	}


	public static void logFor(String title, Long date, String author, String content, String url) {
		boolean success = true;
		StringBuilder message = new StringBuilder("standarAnalyzer: url[" + url + "]---->");
		if(StringUtils.isBlank(title)) {
			message.append("title is null, ");
			success = false;
		}
		if(null == date) {
			message.append("date is null, ");
			success = false;
		}
		if(StringUtils.isBlank(author)) {
			message.append("author is null, ");
			success = false;
		}
		if(StringUtils.isBlank(content)) {
			message.append("content is null.");
			success = false;
		}
		if(!success) {
			logger.error(message);
		}
	}
	
	
	

	private static Forest dict_clh = null;
	static {
		try {
			dict_clh = Library.makeForest("library/default.dic");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
}
